
#include <cairo.h>
#include <gtk/gtk.h>
#include "plot2Dtypes.h"
#include <math.h>
#include <stdlib.h>

typedef struct _ScaledVector ScaledVector;

struct _ScaledVector
{
	float* data;
	unsigned int size;
};

gboolean drawingarea_full = FALSE;
gboolean grid_on = FALSE;




ScaledVector* scaled_vector_new (float xmin, float xmax, float delta)
{
	int i;
				
	ScaledVector* scvector;

	scvector = (ScaledVector*) malloc(sizeof(ScaledVector));
	
	scvector->size = (unsigned int) (((xmax - xmin)/delta)+1);

	scvector ->data = (float*) malloc((scvector->size)*sizeof(float));

	scvector->data[0]= xmin;
	
	for(i=1;i<=(scvector->size)-1;i++)
	{
		scvector->data[i] = scvector->data[i-1]+delta;
	}

	scvector->data[scvector->size] = xmax;

	return (ScaledVector*) scvector;
		
}

void scaled_vector_destroy(ScaledVector* scvector)
{
	free(scvector->data);
	free(scvector);
}


static void show_new(GtkWidget *widget, gpointer data)
{
	GtkWidget* dialog;
	
	dialog = gtk_dialog_new();
	gtk_window_set_title(GTK_WINDOW(dialog), "Information");
	gtk_dialog_run(GTK_DIALOG(dialog));
	gtk_widget_destroy(dialog);
	
}

void on_expose_event (GtkWidget *widget, GdkEventExpose *event, GSList* plotinfo)
{
	int i;
	float  delta;
	static const double dashed[] = {1.0, 0.0, 1.0};
	static int len  = sizeof(dashed) / sizeof(dashed[0]);
	float xmin,  xmax, ymin, ymax;
	GtkEntry* xmin_entry, *xmax_entry;
	GtkStatusbar* statusbar;
	guint sts_context;
	guint msg_id;
	static float d = 60.0, e = 60.0; 
	float width, w;
	float height, h;
	float tx, ty, cx, cy, dw, dh, dx, dy;
	unsigned int n;
	float* x, *y;
	cairo_t* context;
	char xstr[5], ystr[5];
	
	context = gdk_cairo_create(widget->window);
	width  = widget->allocation.width;
	height = widget->allocation.height;

	h = height - 2*e;

	w = width - 2*d;
	
	//cairo_set_line_width (context, 0.5);
	cairo_set_source_rgb(context, 1, 1, 1);
	cairo_rectangle(context,0,0,width,height);
	cairo_fill(context);

	cairo_set_line_width (context, 0.5);
	cairo_set_source_rgb(context, 0, 0, 0);
	cairo_rectangle(context,d,e,w,h);
	cairo_stroke(context);

	statusbar = g_slist_nth_data(plotinfo,2);
	sts_context = gtk_statusbar_get_context_id(statusbar, "Notifications");
	gtk_statusbar_push(statusbar,sts_context," Ready."); 

	if(drawingarea_full)
	{
		gtk_statusbar_pop(statusbar,sts_context);
		gtk_statusbar_push(statusbar,sts_context," Running."); 
		
		xmin_entry = g_slist_nth_data(plotinfo,0);
		xmax_entry = g_slist_nth_data(plotinfo,1);

		xmin = (float) strtod(gtk_entry_get_text (GTK_ENTRY (xmin_entry)), NULL);
		xmax = (float) strtod(gtk_entry_get_text (GTK_ENTRY (xmax_entry)), NULL);

		if(xmin > xmax)
		{
			gtk_statusbar_pop(statusbar,sts_context);
			gtk_statusbar_push(statusbar,sts_context," Error: Axis range xmin bigger than xmax."); 
			return;

		}

		delta = (xmax -xmin)/100.0;
		
		n = (unsigned int) ((xmax - xmin)/delta)+1;

		x = (float*) malloc(n*sizeof(float));

		y = (float*) malloc(n*sizeof(float));

		tx = w/(xmax - xmin);
		cx = d - tx*xmin;

		x[0] = xmin;
		x[n] = xmax;
		
		for(i=1;i<=n-1;i++)
		{
			x[i] =x[i-1]+delta;
		}

		//y[0] = exp(-x[0])*sin(3*x[0]) + 1.0;
		y[0] = x[0]*x[0]*x[0];
		
		ymax = ymin = y[0];
		
		for(i=1;i<=n;i++)
		{
			//y[i] = exp(-x[i])*sin(3*x[i]) + 1.0;
			y[i] = x[i]*x[i]*x[i];

			if(ymax<y[i])	
			{
				ymax = y[i];
			}

			if(ymin>y[i]) 
			{
				ymin = y[i];
			}

		}

		ty = h/(ymax - ymin);
		cy = e - ty*ymin;

		for(i=0;i<=n;i++)
		{
			x[i] = tx*x[i]+cx;
			y[i] = ty*y[i]+cy;
			y[i] = height - y[i];
		}

		cairo_set_source_rgb(context,0,0,0);
		cairo_move_to(context,x[0],y[0]);

		for(i=1;i<=n;i++)
		{
			cairo_line_to(context,x[i],y[i]);

		}

		cairo_stroke(context);

				
		if(grid_on)
		{
			dh = h/10.0;
			dw = w/10.0;

									
			//cairo_set_source_rgb(context, 0, 0, 0);
			//cairo_set_line_width (context, 0.5);
			cairo_set_dash(context, dashed, len, 0);
						
			for(i=1;i<=9;i++)
			{
				cairo_move_to(context,d,e+i*dh);
			//	memset(&ystr,0x00,sizeof(ystr));
			//	sprintf(ystr, "%f", ymin+i*dy);
			//	printf("%s \n",ystr);
			//	cairo_show_text(context, ystr);
				cairo_line_to(context,d+w,e+i*dh);
				
			}

			for(i=1;i<=9;i++)
			{
				cairo_move_to(context,d+i*dw,e);
				cairo_line_to(context,d+i*dw,e+h);
			}

			cairo_stroke(context);

			//Tem gato nesse if 0
			#if 0	
			dy =	 (ymax - ymin)/10.0;
			dx = (xmax - xmin)/10.0;

					
			for(i=0;i<=10;i++)
			{
				//cairo_move_to(context,d/4,height -( ty*(ymin+i*dy)+cy));
				//memset(&ystr,0x00,sizeof(ystr));
				//sprintf(ystr, "%1.2e", ymin+i*dy);
				//cairo_show_text(context, ystr);
			}
			
			for(i=0;i<=10;i++)
			{
				cairo_move_to(context,tx*(xmin+i*dx)+cx-15,e+h+e/4);
				memset(&xstr,0x00,sizeof(xstr));
				sprintf(xstr, "%1.2e", xmin+i*dx);
				printf("xg = %f\n", xmin+i*dx);
				cairo_show_text(context, xstr);
			}
			
			#endif			
		}
					
		free(x);
		free(y);
		cairo_destroy(context);

		gtk_statusbar_pop(statusbar,sts_context);
		gtk_statusbar_push(statusbar,sts_context," Done."); 
	}			

}

void on_plot_button_clicked (GtkButton *plotbutton, GtkWidget* drawing_area)
{
	drawingarea_full = TRUE;
	gtk_widget_queue_draw (drawing_area);
}

void on_grid_check_button_toggled (GtkWidget *grid_check_button, GtkWidget* drawing_area)
{
	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (grid_check_button))) 
    	{
       	grid_on = TRUE;
    	}
	else
	{
            grid_on = FALSE;
	}
	
	gtk_widget_queue_draw (drawing_area);	
}


